package com.mowh.multithreading.worker.thread.worker;

/**
 * @author mowh1gd
 * @create 2023/11/23 15:03
 */
public class Channel {//扮演Channel角色
    private static final int MAX_REQUEST = 100;//队列长度
    private final Request[] requestQueue;
    private int tail;
    private int head;
    private int count;
    private final WorkerThread[] threadPool;

    public Channel(int threads) {//worker线程数量
        this.requestQueue = new Request[MAX_REQUEST];
        this.head = 0;
        this.tail = 0;
        this.count = 0;
        threadPool = new WorkerThread[threads];//初始化线程池（即工人线程集合），之后不再创建新线程，复用线程池中空闲的线程（提高吞吐量）。
        for (int i = 0; i < threadPool.length; i++) {
            threadPool[i] = new WorkerThread("Worker-" + i, this);//实例化每个线程
        }
    }
    public void startWorkers() {
        for (int i = 0; i < threadPool.length; i++) {
            threadPool[i].start();//启动每个线程
        }
    }
    public synchronized void putRequest(Request request) {
        while (count >= requestQueue.length) {//非守护条件：请求数大于队列长度
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        requestQueue[tail] = request;//守护条件：请求数小于队列长度，在队列尾添加请求
        tail = (tail + 1) % requestQueue.length;//添加完后，队尾加1
        count++;
        notifyAll();
    }
    public synchronized Request takeRequest() {
        while (count <= 0) {//非守护条件：队列中请求数小于等于0
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        Request request = requestQueue[head];//守护条件：队列中请求数大于0，队头取出请求
        head = (head + 1) % requestQueue.length;//取完后，队头加1
        count--;
        notifyAll();
        return request;
    }
}
